use std::error::Error;
use std::fmt;
use std::fmt::{Display, Formatter};
use crate::ltools::lconvert;

// 自定义错误类型，用于表示解析过程中的问题
#[derive(Debug, PartialEq)]
pub enum ParseError {
    InsufficientBytes,
    InvalidData,
}

impl fmt::Display for ParseError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            ParseError::InsufficientBytes => {
                write!(f, "数据长度不符")
            }
            ParseError::InvalidData => write!(f, "无效数据:"),
        }
    }
}

impl Error for ParseError {}


pub struct ByteParser<'a>{
    bytes: &'a [u8],
    pos:usize,
    t_len:usize,
}

impl<'a> ByteParser<'a> {

    pub fn new(bytes: &'a [u8]) -> Self{
        ByteParser{
            bytes,
            pos:0,
            t_len:bytes.len()
        }
    }
    /* 解析 u8 数据 */
    pub fn parse_u8(&mut self) -> Result<u8, ParseError> {
        if self.pos + 1 > self.t_len { return Err(ParseError::InsufficientBytes)}
        let num = self.bytes[self.pos];
        self.pos += 1;
        Ok(num)
    }

    /* 解析 u16 数据 */
    pub fn parse_u16(&mut self) -> Result<u16, ParseError> {
        let n_len = self.pos + 2;
        if n_len > self.t_len { return Err(ParseError::InsufficientBytes)}
        let num:u16 = lconvert::byte_to_u16(&self.bytes[self.pos..n_len]);
        self.pos = n_len;
        Ok(num)
    }

    /* 解析 u32 数据 */
    pub fn parse_u32(&mut self) -> Result<u32, ParseError> {
        let n_len = self.pos + 4;
        if n_len > self.t_len { return Err(ParseError::InsufficientBytes)}
        let num = lconvert::byte_to_u32(&self.bytes[self.pos..n_len]);
        self.pos = n_len;
        Ok(num)
    }

    /* 解析 u32 数据 */
    pub fn parse_u64(&mut self) -> Result<u64, ParseError> {
        let n_len = self.pos + 8;
        if n_len > self.t_len { return Err(ParseError::InsufficientBytes)}
        let num = lconvert::byte_to_u64(&self.bytes[self.pos..n_len]);
        self.pos = n_len;
        Ok(num)
    }

    pub fn parse_str_u16(&mut self) -> Result<String, ParseError> {
        let str_len = self.parse_u16()?;
        let n_len = self.pos + str_len as usize;
        if n_len > self.t_len { return Err(ParseError::InsufficientBytes)}
        let data = String::from_utf8_lossy(&self.bytes[self.pos..n_len]).into_owned();
        self.pos = n_len;
        Ok(data)
    }

    pub fn parse_str_u32(&mut self) -> Result<String, ParseError> {
        let str_len = self.parse_u32()?;
        let n_len = self.pos + str_len as usize;
        if n_len > self.t_len { return Err(ParseError::InsufficientBytes)}
        let data = String::from_utf8_lossy(&self.bytes[self.pos..n_len]).into_owned();
        self.pos = n_len;
        Ok(data)
    }


}


